package com.healthteches.read;

import de.beckhoff.jni.Convert;
import de.beckhoff.jni.JNIByteBuffer;
import de.beckhoff.jni.tcads.AdsCallDllFunction;
import de.beckhoff.jni.tcads.AmsAddr;

public class ReadDouble {

  public static void main(String[] args) throws Exception {
    long nPort, nErr;
    AmsAddr addr = new AmsAddr();
    double lreal;
    JNIByteBuffer dataBuff = new JNIByteBuffer(8);
    byte[] dataVal1 = new byte[8];
    JNIByteBuffer hdlBuff = new JNIByteBuffer(4);
    JNIByteBuffer symBuff = new JNIByteBuffer(Convert.StringToByteArr("MAIN.PLCVar"));
    // Open communication
    nPort = AdsCallDllFunction.adsPortOpen();
    nErr = AdsCallDllFunction.getLocalAddress(addr);
    addr.setPort(801);

    nErr =
        AdsCallDllFunction.adsSyncReadWriteReq(
            addr,
            0xF003,
            0x0,
            hdlBuff.getUsedBytesCount(),
            hdlBuff,
            symBuff.getUsedBytesCount(),
            symBuff);
    if (nErr != 0) {
      System.out.println("Error: Get handle: 0x" + Long.toHexString(nErr));
    }
    int hdlBuffToInt = Convert.ByteArrToInt(hdlBuff.getByteArray());
    nErr = AdsCallDllFunction.adsSyncReadReq(addr, 0xF005, hdlBuffToInt, 0x8, dataBuff);
    dataVal1 = dataBuff.getByteArray();
    lreal = byteToDouble(dataVal1);
    System.out.print(lreal);
  }

  public static double byteToDouble(byte[] b) {
    long l;
    l = b[0];
    l &= 0xff;
    l |= ((long) b[1] << 8);
    l &= 0xffff;
    l |= ((long) b[2] << 16);
    l &= 0xffffff;
    l |= ((long) b[3] << 24);
    l &= 0xffffffffl;
    l |= ((long) b[4] << 32);
    l &= 0xffffffffffl;
    l |= ((long) b[5] << 40);
    l &= 0xffffffffffffl;
    l |= ((long) b[6] << 48);
    l |= ((long) b[7] << 56);
    return Double.longBitsToDouble(l);
  }

  public static byte[] doubleToByte(double d) {
    byte[] b = new byte[8];
    long l = Double.doubleToLongBits(d);
    for (int i = 0; i < b.length; i++) {
      b[i] = new Long(l).byteValue();
      l = l >> 8;
    }
    return b;
  }
}
